package edu.guet.cn.blogbasics.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * @Auther: hejianding
 * @Date: 2021/4/8 8:55
 * @Version: 1.0
 */
public class JwtTokenUtils {
    private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtils.class);

    public static final String TOKEN_HEADER = "Authorization";
    public static final String TOKEN_PREFIX = "Bearer";

    //密钥,用于signature签名（部分）的解密
    private static final String PRIMARY_KEY = "JWTSCRETE";
    //签发者
    private static final String ISS = "Gent.he";
    //角色的key
    private static final String ROLE_CLAIMS = "role";

    //过期时间3600秒，一个100小时
    private static final long EXPIRATION=360000L;
    //记住我功能，时间变为1000小时
    private static final long EXPIRATION_REMEMBER = 3600000L;

    /**
     * 创建token
     */
    public static String createToken(String userName, List<String> roles, boolean isRememberMe){
        long expiration = isRememberMe ? EXPIRATION_REMEMBER : EXPIRATION;
        HashMap<String, Object> map = new HashMap<>();
        map.put(ROLE_CLAIMS,roles);
        return Jwts.builder()
                //用...对签名进行加密，PRIMARY_KEY是密钥
                .signWith(SignatureAlgorithm.HS512, PRIMARY_KEY)
                //设置角色名
                .setClaims(map)
                //设置签发者
                .setIssuer(ISS)
                .setSubject(userName)
                .setIssuedAt(new Date())
                .setExpiration(new Date(System.currentTimeMillis() + expiration * 1000))
                .compact();
    }

    /**
     * 从token中获取用户名
     */
    public static String getUsername(String token){
        return getTokenBody(token).getSubject();
    }

    /**
     * 获取用户角色
     */
    public static List<String> getUserRole(String token){
        return (List<String>) getTokenBody(token).get(ROLE_CLAIMS);
    }

    /**
     * 判断token是否过期
     */
    public static boolean isExpiration(String token){
        try {
            return getTokenBody(token).getExpiration().before(new Date());
        } catch (ExpiredJwtException e) {
            logger.warn("[" + token + "]" + "is expired.");
            return true;
        }
    }

    /**
     * 获取token的body
     * @param token
     * @return
     */
    private static Claims getTokenBody(String token){
        return Jwts.parser()
                .setSigningKey(PRIMARY_KEY)
                .parseClaimsJws(token)
                .getBody();
    }
}
